package com.demo.uitls;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.demo.model.bo.EpolicyEmailSendResult;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.mail.EmailAttachment;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2017/9/5.
 */
public class SendCloudHelper {

    private static final String DEFAULT_API_USER = "bxs_edm";
    private static final String DEFAULT_API_KEY = "beAH2jxfLOUxWud6";
    private static final String DEFAULT_API_URL = "http://api.sendcloud.net/apiv2/mail/sendtemplate";

    private String apiUser = DEFAULT_API_USER;
    private String apiKey = DEFAULT_API_KEY;
    private String apiUrl = DEFAULT_API_URL;

    public String getApiUser() {
        return apiUser;
    }

    public void setApiUser(String apiUser) {
        this.apiUser = apiUser;
    }

    public String getApiKey() {
        return apiKey;
    }

    public void setApiKey(String apiKey) {
        this.apiKey = apiKey;
    }

    public String getApiUrl() {
        return apiUrl;
    }

    public void setApiUrl(String apiUrl) {
        this.apiUrl = apiUrl;
    }

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private static final Integer STATSU_CODE_SUCCEED = 200;

    /**
     * 异步发送邮件
     *
     * @param subject
     * @param templateName
     * @param receiverEmail
     * @param attachFileUrlList
     */
    public void sendMailByAsynchronous(final String subject, final String templateName, final Map<String, List<String>> sub, String receiverEmail, final List<String> attachFileUrlList) {
        Map<String, String> attachmentUrlMap = new HashMap<>();
        //附件
        if (CollectionUtils.isNotEmpty(attachFileUrlList)) {
            for (String url : attachFileUrlList) {
                String fileName = url.lastIndexOf("/") >= 0 ? url.substring(url.lastIndexOf("/") + 1) : url;
                attachmentUrlMap.put(fileName, url);
            }
        }
        sendMailByAsynchronous(subject, templateName, sub, receiverEmail, attachmentUrlMap);
    }


    /**
     * 异步发送邮件
     *
     * @param subject
     * @param templateName
     * @param sub
     * @param receiverEmail
     * @param attachFileUrlMap
     */
    public void sendMailByAsynchronous(final String subject, final String templateName, final Map<String, List<String>> sub, String receiverEmail, final Map<String, String> attachFileUrlMap) {
        final String from = "support@winbaoxian.com";
        final String fromName = "微易邮件服务器";
        final List<String> tos = new ArrayList<>();
        if (StringUtils.isBlank(subject) || StringUtils.isBlank(templateName) || StringUtils.isBlank(receiverEmail)) {
            return;
        }
        //收件人地址
        final List<String> emailAddressList = new ArrayList<>();
        emailAddressList.add(receiverEmail);
        //附件
        final List<EmailAttachment> attachmentList = new ArrayList<>();
        if (MapUtils.isNotEmpty(attachFileUrlMap)) {
            for (String fileName : attachFileUrlMap.keySet()) {
                EmailAttachment attachment = new EmailAttachment();
                attachment.setPath(attachFileUrlMap.get(fileName));
                attachment.setName(fileName);
                attachmentList.add(attachment);
            }
        }
        //发给投保人
        tos.add(receiverEmail);
        new Thread(() -> {
            try {
                logger.info("异步发送{}", subject);
                sendTemplateEmail(from, fromName, emailAddressList, attachmentList, sub, subject, templateName);
            } catch (Exception ex) {
                logger.info("发送邮件异常");
                ex.printStackTrace();
            }
        }).start();
    }

    /**
     * 异步发送邮件
     *
     * @param subject
     * @param templateName
     */
    public void sendMailByAsynchronous(final String subject, final String templateName, final Map<String, List<String>> sub, final List<String> emailAddressList, final List<EmailAttachment> attachmentList) {
        final String from = "support@winbaoxian.com";
        final String fromName = "微易邮件服务器";
        if (StringUtils.isBlank(subject) || StringUtils.isBlank(templateName) || CollectionUtils.isEmpty(emailAddressList) || CollectionUtils.isEmpty(attachmentList)) {
            return;
        }
        new Thread(() -> {
            try {
                logger.info("异步发送{}", subject);
                sendTemplateEmail(from, fromName, emailAddressList, attachmentList, sub, subject, templateName);
            } catch (Exception ex) {
                logger.error("发送邮件异常", ex);
            }
        }).start();
    }

    private CloseableHttpClient createHttpClient(int reqTimeout) {
        RequestConfig defaultRequestConfig = RequestConfig.custom()
                .setSocketTimeout(reqTimeout)
                .setConnectTimeout(reqTimeout)
                .setConnectionRequestTimeout(reqTimeout)
                .build();
        return HttpClients.custom()
                .setDefaultRequestConfig(defaultRequestConfig)
                .build();
    }

    public EpolicyEmailSendResult sendTemplateEmail(String fromAddress, String fromName, List<String> emailAddressList, List<EmailAttachment> attachmentList, Map<String, List<String>> sub, String subject, String templateName) throws IOException, URISyntaxException {
        JSONObject json = new JSONObject();
        json.put("to", emailAddressList);
        json.put("sub", sub);

        CloseableHttpClient httpClient = createHttpClient(6000);
        HttpPost httpPost = new HttpPost(apiUrl);
        MultipartEntityBuilder entity = MultipartEntityBuilder.create();
        entity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        entity.setCharset(Charset.forName("UTF-8"));
        ContentType TEXT_PLAIN = ContentType.create("text/plain", Charset.forName("UTF-8"));
        entity.addTextBody("apiUser", apiUser, TEXT_PLAIN);
        entity.addTextBody("apiKey", apiKey, TEXT_PLAIN);
        entity.addTextBody("xsmtpapi", json.toJSONString(), TEXT_PLAIN);
        entity.addTextBody("templateInvokeName", templateName, TEXT_PLAIN);
        entity.addTextBody("from", fromAddress, TEXT_PLAIN);
        entity.addTextBody("fromName", fromName, TEXT_PLAIN);
        entity.addTextBody("subject", subject, TEXT_PLAIN);
        //添加附件
        if (!CollectionUtils.isEmpty(attachmentList)) {
            ContentType OCTEC_STREAM = ContentType.create("application/octet-stream", Charset.forName("UTF-8"));
            logger.info("sendTemplateEmail add file start");
            for (EmailAttachment attachment : attachmentList) {
                URL fileUrl = new URL(attachment.getPath());
                InputStream inputStream = fileUrl.openStream();
                entity.addBinaryBody("attachments", inputStream, OCTEC_STREAM, attachment.getName());
                logger.info("sendTemplateEmail add file end");
            }
        }
        httpPost.setEntity(entity.build());
        HttpResponse response = httpClient.execute(httpPost);
        logger.info("http client response ");
        // 处理响应
        EpolicyEmailSendResult result = new EpolicyEmailSendResult();
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            // 正常返回, 解析返回数据
            JSONObject jsonObject = JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
            if (jsonObject.getBoolean("result") && STATSU_CODE_SUCCEED.equals(jsonObject.getInteger("statusCode"))) {
                result.setSucceed(true);
                logger.info("send epolicy email succeed email: " + JSON.toJSONString(emailAddressList));
            } else {
                result.setSucceed(false);
                result.setFailedMessage(jsonObject.getString("message"));
                logger.info("send epolicy email falied: " + jsonObject.getString("message"));
            }
        } else {
            logger.info("send email failed: http status" + response.getStatusLine().getStatusCode());
            result.setSucceed(false);
            result.setFailedMessage("网络请求失败");
        }

        httpPost.releaseConnection();
        return result;
    }


    public void main(String[] args) {
        List<String> tosList = new ArrayList<>();
        tosList.add("wxq@winbaoxian.com");
        try {
            List<EmailAttachment> attachmentList = new ArrayList<>();
            EmailAttachment attachment = new EmailAttachment();
            attachment.setName("wxq_d94632b2942d4bbcb91c2cc221dae60e.pdf");
            attachment.setPath("https://res.winbaoxian.com/e-policy/test-pdf/20171106/d94632b2942d4bbcb91c2cc221dae60e.pdf");
            attachmentList.add(attachment);
            Map<String, List<String>> sub = new HashMap<>();
            List<String> productNameList = new ArrayList<>();
            productNameList.add("杭州微易中小企业团意DIY");
            sub.put("%productName%", productNameList);

            List<String> applicantNameList = new ArrayList<>();
            applicantNameList.add("台州锐博新能源科技有限公司");
            sub.put("%applicantName%", applicantNameList);

            List<String> policyNoList = new ArrayList<>();
            policyNoList.add("11209601900361961841");
            sub.put("%policyNo%", policyNoList);

            List<String> payAmountList = new ArrayList<>();
            payAmountList.add("1950.0");
            sub.put("%payAmount%", payAmountList);

            List<String> insureDurationList = new ArrayList<>();
            insureDurationList.add("2017年08月13日 00时 至 2018年08月12日 00时");
            sub.put("%insureDuration%", insureDurationList);

            List<String> policyUrlList = new ArrayList<>();
            policyUrlList.add("https://res.winbaoxian.com/e-policy/test-pdf/20171106/d94632b2942d4bbcb91c2cc221dae60e.pdf");
            sub.put("%policyUrl%", policyUrlList);
            //("", "", tosList, attachmentList, sub, "%applicantName%请查收您的电子保单", "electronic_policy_template");
            sendMailByAsynchronous("%applicantName%请查收您的电子发票", "electronic_invoice_template", sub, tosList, attachmentList);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
